package ru.urfc.portal.services;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.urfc.portal.dao.BasePersistence;
import ru.urfc.portal.model.Client;
import ru.urfc.portal.model.Branch;
import ru.urfc.portal.model.NotificationSettings;
import ru.urfc.portal.model.accounting.Invoice;
import ru.urfc.portal.model.admins.User;
import ru.urfc.portal.model.radio.Device;
import ru.urfc.portal.model.radio.DeviceCertificate;
import ru.urfc.portal.model.radio.NetLicense;
import ru.urfc.portal.model.radio.NetWithLicense;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Properties;

import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.ejb.Timer;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

@Stateless
public class NotificationTimer {

	public boolean debug;
	public boolean debugEmail = false;

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	@PersistenceContext(name = "branch1", unitName = "branch1")
	private EntityManager branch1EntityManager;

	@PersistenceContext(name = "branch2", unitName = "branch2")
	private EntityManager branch2EntityManager;

	@EJB
	BasePersistence basePersistence;
	// @Resource
	// private javax.mail.Session session;

	@PersistenceContext(name = "sys", unitName = "sys")
	public EntityManager sys;

	// @PersistenceContext(name="branch1", unitName = "branch1")
	// public EntityManager s1;
	//
	// @PersistenceContext(name="branch2", unitName = "branch2")
	// public EntityManager s2;
	//	
	// @PersistenceContext(name="branch2", unitName = "branch3")
	// public EntityManager s3;
	//
	// @PersistenceContext(name="branch2", unitName = "branch4")
	// public EntityManager s4;

	@PersistenceContext(name = "eis", unitName = "eis")
	public EntityManager eis;

	public NotificationTimer() {
		// TODO Auto-generated constructor stub
	}

	public Calendar today;

	public String getGlobalEnd() {
		return "--\nС уважением,\nПортал интерактивного обслуживания\nФГУП \"РЧЦ УрФО\"\nhttps://portal.urfc.ru/";
	}

	/*
	 * eis.DeviceCertificate (deviceGuid, seria, number, issueDate, expireDate)
	 * spectr1.Device (guid, net) spectr1.Invoice (contragent, isPaid, Name,
	 * number, date) spectr1.NetLicense (state, number, issueDate, expireDate,
	 * net) spectr1.NetWithLicense(contragent) spectr1.Contragent.email
	 * sys.NotificationSettings (client,useGlobal,global
	 * deviceCertificateExpiring, netLicenseExpiring, expirationNotifyInterval
	 * invoiceUnpaidDays, invoiceUnpaidNotifyInterval sys.Client(contragent)
	 */

	// HashMap<String, String> devGuidToAgent =
	public Calendar DateCal(Date date) {
		Calendar result = Calendar.getInstance();
		result.setTime(date);
		return result;
	}

	// public class ContragentPair {
	// public Long filId;
	// public Contragent contragent;
	// }
	//
	// public class LicPair {
	// public Long filId;
	// public NetLicense lic;
	// }

	public class DevicePair {
		public String filCode;
		public Device device;

		public DevicePair(String filCode, Device device) {
			this.filCode = filCode;
			this.device = device;
		}
	}

	// public class InvoicePair {
	// public Long filId;
	// public Invoice invoice;
	// }

	Calendar sixty;

	public void go2() {
		Calendar current = Calendar.getInstance();
		today = new GregorianCalendar(current.get(Calendar.YEAR), current
				.get(Calendar.MONTH), current.get(Calendar.DAY_OF_MONTH));
		sixty = (Calendar) today.clone();
		sixty.add(Calendar.DAY_OF_MONTH, 60);
		//scanCerts();
		scanInv();
		//scanLics();
	}

	public void go() {
		Calendar current = Calendar.getInstance();
		today = new GregorianCalendar(current.get(Calendar.YEAR), current
				.get(Calendar.MONTH), current.get(Calendar.DAY_OF_MONTH));
		sixty = (Calendar) today.clone();
		sixty.add(Calendar.DAY_OF_MONTH, 60);

		try {
			scanCerts();
		} catch (Exception e) {
			logger.warn("Certificate notification failed " + e.getMessage());
			e.printStackTrace();
		}

		try {
			scanInv();
		} catch (Exception e) {
			logger.warn("Invoice notification failed " + e.getMessage());
			e.printStackTrace();
		}

		try {
			scanLics();
		} catch (Exception e) {
			logger.warn("License notification failed " + e.getMessage());
			e.printStackTrace();
		}

		// today.add(Calendar.DAY_OF_MONTH, -30); //TODO

		// fillCerts();
		// fillInvs();
		// fillLics();
		// fillAgentToNS();
		// fillCertToAgent();
		//
		// NotifyCerts();
		// NotifyLics();
		// NotifyInvs();

		// List<Invoice> invs = getInvoices();
		// List<Object[]> nls = getNLs();

		// System.out.println(String.format("\ninv %s cert %s lic %s",
		// invs.size(), certs.size(), lics.size()));
		// System.out.println(String.format("\nagent2ns %s cert2agent %s",
		// agentToNS.size(), certToAgent.size(), lics.size()));
	}

	public List<User> getUsers(Client client) {
		return getUsers(sys, client);
	}

	public static List<User> getUsers(EntityManager sys, Client client) {
		Query query = sys.createQuery(
				"select user from User user where user.client = :client")
				.setParameter("client", client);
		return query.getResultList();
	}

	// private void fillAgentToNS() {
	// agentToNS = new HashMap<Long, NotificationSettings>();
	// String nsQ =
	// "select ns from NotificationSettings ns where ns.client.accessEnabled = true";
	// Query query = sys.createQuery(nsQ);
	// List<NotificationSettings> nss = query.getResultList();
	// for (NotificationSettings ns : nss) {
	// if (ns.isGlobal()) {
	// GlobalInvoiceDays = ns.getInvoiceUnpaidDays();
	// GlobalInvoiceInterval = ns.getInvoiceUnpaidNotifyInterval();
	// GlobalCertLicInterval = ns.getExpirationNotifyInterval();
	// } else {
	// Long agentId = ns.getClient().getContragentId();
	// agentToNS.put(agentId, ns);
	// }
	// }
	// }
	//
	// private void fillNSByAgentId(Long id) {
	// if (agentToNS.keySet().contains(id)) {
	// NotificationSettings ns = agentToNS.get(id);
	// InvoiceDays = ns.getInvoiceUnpaidDays();
	// InvoiceInterval = ns.getInvoiceUnpaidNotifyInterval();
	// CertLicInterval = ns.getExpirationNotifyInterval();
	// } else {
	// InvoiceDays = GlobalInvoiceDays;
	// InvoiceInterval = GlobalInvoiceInterval;
	// CertLicInterval = GlobalCertLicInterval;
	// }
	//
	// }

	public List<String> filCodes = new ArrayList<String>(); // spectr ems
	public List<EntityManager> ems = new ArrayList<EntityManager>(); // spectr
																		// ems

	// private int InvoiceDays;
	// private int InvoiceInterval;
	// private int CertLicInterval;
	//
	// private int GlobalInvoiceDays;
	// private int GlobalInvoiceInterval;
	// private int GlobalCertLicInterval;

	private SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy");

	// private List<LicPair> lics;
	// private List<DeviceCertificate> certs;
	// private List<Invoice> invs;

	// HashMap<DeviceCertificate, DevicePair> cert2Device = null;
	// HashMap<DeviceCertificate, DevicePair>

	// HashMap<Long, NotificationSettings> agentToNS = null;

	private long DayDiff(Date date) {
		return (today.getTimeInMillis() - DateCal(date).getTimeInMillis())
				/ (1000 * 60 * 60 * 24);
	}

	// private void sendEmail(String email, String subj, String body) {
	// System.out.println(subj);
	// System.out.println(body);
	// }
	// private void notifyInv(Client client, Invoice inv) {
	// List<User> users = getUsers(client);
	// for (User user : users) {
	// String subj = "Неоплаченный счет РЧЦ УрФО № " + inv.getNumber();
	// String body = String
	// .format(
	// "%s Вас (Вашего предприятия) имеется неоплаченный счет  №%s от %s на сумму %,.2f.\n\n"
	// + "Просим оплатить счет в ближайшее время.%s",
	// getBodyStart(user), inv.getNumber(), df.format(inv
	// .getDate()), inv.amountTotal, getBodyEnd());
	//
	// sendEmail(user.getEmail(), subj, body);
	// }
	// }
	private void notifyInvs(Client client, List<Invoice> invs) {
		if (invs.size() == 0)
			return;
		// if (invs.size() == 1) {
		// notifyInv(client, invs.get(0));
		// return;
		// }
		List<User> users = getUsers(client);
		for (User user : users) {
			String subj = "Портал РЧЦ УрФО: напоминание об оплате счетов";
			String body = "Уважаемый Клиент РЧЦ УрФО!\n\nИнформируем Вас о том, что в настоящее время Вами не исполняются обязательства по оплате услуг нашего предприятия.\n\n"
					+ "Предлагаем оплатить выставленный счет (счета)";
			BigDecimal sum = new BigDecimal(0);
			for (Invoice inv : invs) {
				sum = sum.add(inv.amountTotal);
				body += String
						.format(
								"\n№ %s от %s на сумму %,.2f рублей, в том  числе НДС;",
								inv.getNumber(), df.format(inv.getDate()),
								inv.amountTotal);
			}
			body += String
					.format(
							"\n\nобщая сумма задолженности, включая НДС, %,.2f рублей\n\n",
							sum);
			body += "Напоминаем наши банковские реквизиты:\n\n"
					+ "кор.счет 30101810500000000674 в Уральском банке  Сбербанка РФ г.Екатеринбург,\n"
					+ "р/с 40502810016160100031 в Кировском ОСБ №7003 г.Екатеринбург,\n"
					+ "ИНН 6660155354, БИК  046577674, КПП 666001001.\n\n"
					+ getGlobalEnd();
			sendEmail(user.getEmail(), subj, body);
		}
	}

	private void notifyCert(Client client, Device device, DeviceCertificate cert) {
		List<User> users = getUsers(client);
		for (User user : users) {
			String subj = "Портал РЧЦ УрФО: напоминение об окончании срока регистрации РЭС";
			String body = "Уважаемый Клиент РЧЦ УрФО!\n\n";
			body += String
					.format("Информируем Вас о том, что %s заканчивается срок действия разрешения на право эксплуатации радиоэлектронных средств: %s %s, %s %s, %s\n\n", 
							df.format(cert.expireDate),	device.type.name, device.number, cert.seria, cert.number, df.format(cert.issueDate));
			
			body += "В настоящее время регистрация радиоэлектронных средств осуществляется Федеральной службой по надзору в сфере связи, информационных технологий и массовых коммуникаций, на территории Свердловской области – ее территориальным органом, находящимся по адресу: г. Екатеринбург, пр. Ленина, д. 39 (тел. 359-01-80).\n\n";
			body += "Свидетельство о регистрации радиоэлектронного средства является именным документом и дает владельцу право на его использование\n\n";
			body += "Для получения документов о присвоении позывных сигналов опознавания для радиоэлектронных средств Вам необходимо  обратиться во ФГУП «РЧЦ УрФО» с заявлением, в котором должны быть указаны типы, заводские номера, рабочие частоты РЭС и ранее присвоенные позывные сигналы.";
			body += "Если дальнейшее использование  радиоэлектронных средств не планируется, просим  направить в адрес ФГУП «РЧЦ УрФО» соответствующее уведомление и документы, подтверждающие, что зарегистрированные ранее радиоэлектронные средства выведены из эксплуатации.\n\n";
			body += getGlobalEnd();
			sendEmail(user.getEmail(), subj, body);
		}
	}

	private String getBodyStart(User user) {
		return String.format("Здравствуйте!\n\nИнформируем Вас о том, что у ",
				user.lastName, user.firstName, user.lastName);
	}

	private String getBodyEnd() {
		return "\n\nС уважением,\nПортал РЧЦ УрФО\nportal@urfc.ru\nhttps://portal.urfc.ru/";
	}

	private void notifyLic(Client client, NetWithLicense net, NetLicense lic) {
		List<User> users = getUsers(client);
		for (User user : users) {

			String subj = "Портал РЧЦ УрФО: напоминание об окончании срока действия разрешения на использование частот";
			String body = "Уважаемый Клиент РЧЦ УрФО!\n\n";
			body += String.format("Информируем Вас о том, что %s заканчивается срок действия %s, %s, %s",
							df.format(lic.expireDate), net.name, lic.number, df.format(lic.issueDate));
			body += "Для продления срока действия разрешения на использование радиочастот Вам  необходимо обратиться в Федеральную службу по надзору в сфере связи, информационных технологий и массовых коммуникаций с заявлением, оформленным по установленной форме, не менее чем за 30 дней до истечения срока действия разрешения на использование радиочастот.\n\n";
			body += "Продление срока действия разрешения на использование  радиочастот может осуществляться, если условия использования радиочастот не изменились. При изменении условий использования радиочастот оформление разрешения на использование радиочастот осуществляется на основании заключения радиочастотной службы.\n\n";
			body += "В том случае, если Вами не планируется дальнейшее использование радиочастот, прошу направить в адрес ФГУП «РЧЦ УрФО» соответствующее уведомление и документы, подтверждающие, что зарегистрированные ранее по указанному разрешению на использование радиочастот радиоэлектронные средства выведены из эксплуатации.\n\n";
			body += getGlobalEnd();
			sendEmail(user.getEmail(), subj, body);
		}
	}

	public boolean shouldNotifyLic(Date expireDate, NotificationSettings ns) {
		if (!ns.isNetLicenseExpiring())
			return false;
		long days = DayDiff(expireDate);
		return (days + 60 >= 0)
				&& (days + 60) % ns.getExpirationNotifyInterval() == 0;
	}

	public boolean shouldNotifyCert(Date expireDate, NotificationSettings ns) {
		if (!ns.isDeviceCertificateExpiring())
			return false;
		long days = DayDiff(expireDate);
		return (days + 60 >= 0)
				&& (days + 60) % ns.getExpirationNotifyInterval() == 0;
	}

	public boolean shouldNotifyInv(Date expireDate, NotificationSettings ns) {
		if (!ns.isNotifyAboutUnpaidInvoices())
			return false;
		long days = DayDiff(expireDate);
		return ((days >= ns.getInvoiceUnpaidDays()) && (days - ns
				.getInvoiceUnpaidDays())
				% ns.getInvoiceUnpaidNotifyInterval() == 0);
	}

	public NotificationSettings GlobalNS;

	// private void NotifyInvs() {
	// for (Invoice inv : invs) {
	// fillNSByAgentId(inv.getContragent().getId());
	// long days = DayDiff(inv.getDate());
	// if ((days >= InvoiceDays)
	// && (days - InvoiceDays) % InvoiceInterval == 0) {
	// NotifyInv(inv.getContragent().email, inv);
	// }
	// }
	// }
	//
	// private void NotifyLics() {
	// for (NetLicense lic : lics) {
	// Contragent agent = lic.getNet().getContragent();
	// fillNSByAgentId(agent.getId());
	// long days = DayDiff(lic.expireDate);
	// if ((days + 60 >= 0) && (days + 60) % CertLicInterval == 0) {
	// NotifyLic(agent.email, lic);
	// }
	// }
	// }
	//
	// private void NotifyCerts() {
	// for (DeviceCertificate cert : certs) {
	// Contragent agent = certToAgent.get(cert);
	// fillNSByAgentId(agent.getId());
	// long days = DayDiff(cert.expireDate);
	// if ((days + 60 >= 0) && (days + 60) % CertLicInterval == 0) {
	// NotifyCert(agent.email, cert);
	// }
	// }
	// }

	public Client getClient(String filCode, long agentId) {
		String clientQ = "select cl from Client cl where cl.contragentId = :agentId and cl.branch.code = :code and cl.accessEnabled = true";
		Query query = sys.createQuery(clientQ).setParameter("agentId", agentId)
				.setParameter("code", filCode);
		List<Client> clients = query.getResultList();
		return clients.size() > 0 ? clients.get(0) : null;

	}

	public NotificationSettings getGlobalNS() {
		if (GlobalNS == null)
			setGlobalNS();
		return GlobalNS;
	}

	public void setGlobalNS() {
		String nsQ = "select ns from NotificationSettings ns where IsGlobal = true";
		Query query = sys.createQuery(nsQ);
		GlobalNS = (NotificationSettings) query.getResultList().get(0);
	}

	public NotificationSettings getNS(Client client) {
		NotificationSettings ns = client.getNotificationSettings();
		return ns.isUseGlobal() ? GlobalNS : ns;
	}

	public void scanInv() {
		System.out.println("Invs");
		String invQ = "select i from Invoice i where i.isPaid = false and i.date < :today order by i.contragent.id";
		// if (true) {
		// invQ += " and i.contragent.id = 1";
		// }
		for (int i = 0; i < ems.size(); i++) {
			EntityManager em = ems.get(i);
			Query query = em.createQuery(invQ).setParameter("today", today,
					TemporalType.DATE);
			List<Invoice> invs = null;
			try {
				invs = query.getResultList();
			} catch (Exception e) {
				logger.info("Bad DB structure {}", e.getMessage());
				e.printStackTrace();
				continue;
			}
			Client prevClient = null;
			List<Invoice> currentInvs = new ArrayList<Invoice>();
			for (Invoice inv : invs) {
				if (inv.getContragent() == null) {
					logger.warn("Contragent not found for invoice "
							+ inv.getNumber() + " " + inv.getDate());
					continue;
				}
				Client client = getClient(filCodes.get(i), inv.getContragent()
						.getId());
				if (prevClient != null
						&& (client == null || client.getId() != prevClient
								.getId())) {
					notifyInvs(prevClient, currentInvs);
					currentInvs = new ArrayList<Invoice>();
				}
				prevClient = client;
				if (client != null) {
					NotificationSettings ns = getNS(client);
					if (shouldNotifyInv(inv.getDate(), ns))
						currentInvs.add(inv);
				}
			}
			if (prevClient != null)
				notifyInvs(prevClient, currentInvs);
		}
	}

	public DevicePair getDevicePair(String guid) {
		for (int i = 0; i < ems.size(); i++) {
			EntityManager em = ems.get(i);
			Query deviceQuery = em.createQuery(
					"select d from Device d where d.guid = :guid")
					.setParameter("guid", guid);
			List<Device> devList = deviceQuery.getResultList();
			if (devList.size() > 0)
				return new DevicePair(filCodes.get(i), devList.get(0));
		}
		return null;
	}

	public void scanCerts() {
		System.out.println("Certs");
		String dcQ = "select dc from DeviceCertificate dc "
				+ "where dc.expireDate BETWEEN :today AND :sixty and dc.status=:status";
		List<DeviceCertificate> certs = eis.createQuery(dcQ).setParameter(
				"status", DeviceCertificate.STATUS_ACTIVE).setParameter(
				"today", today, TemporalType.DATE).setParameter("sixty", sixty,
				TemporalType.DATE).getResultList();
		for (DeviceCertificate cert : certs) {
			DevicePair devpair = getDevicePair(cert.getDeviceGuid());
			if (devpair == null) {
				logger.warn("Device not found for " + cert.getDeviceGuid());
				continue;
			}
			Device device = devpair.device;
			Client client = getClient(devpair.filCode, device.getContragent()
					.getId()); // filId, agentId);
			if (client != null) {
				NotificationSettings ns = getNS(client);
				if (shouldNotifyCert(cert.expireDate, ns))
					notifyCert(client, device, cert);
			}
		}

	}

	public void scanLics() {
		System.out.println("Lics");
		String nlQ = "select nl from NetLicense nl " + // JOIN nl.net n
				"where nl.expireDate BETWEEN :today AND :sixty and nl.state.text = :text";
		for (int i = 0; i < ems.size(); i++) {
			EntityManager em = ems.get(i);
			Query query = em.createQuery(nlQ).setParameter("today", today,
					TemporalType.DATE).setParameter("sixty", sixty,
					TemporalType.DATE).setParameter("text", "Действительно");
			List<NetLicense> lics = query.getResultList();
			for (NetLicense lic : lics) {
				NetWithLicense net = lic.getNet();
				if (net == null) {
					logger.warn("Net not found for license " + lic.issueDate
							+ " " + lic.number);
					continue;
				}
				if (net.getContragent() == null) {
					logger.warn("Contragent not found for net " + net.name);
					continue;
				}

				Client client = getClient(filCodes.get(0), net.getContragent()
						.getId()); // filId, agentId);

				if (client != null) {
					NotificationSettings ns = getNS(client);
					if (shouldNotifyLic(lic.expireDate, ns))
						notifyLic(client, net, lic);
				}
			}
		}
	}

	// private void fillLics() {
	// String nlQ = "select nl from NetLicense nl " + // JOIN nl.net n
	// "where nl.expireDate BETWEEN :today AND :sixty";
	// Calendar sixty = (Calendar) today.clone();
	// sixty.add(Calendar.DAY_OF_MONTH, 60);
	//
	// Query query = s1.createQuery(nlQ).setParameter("today", today,
	// TemporalType.DATE).setParameter("sixty", sixty,
	// TemporalType.DATE);
	// lics = query.getResultList();
	// query = s2.createQuery(nlQ).setParameter("today", today,
	// TemporalType.DATE).setParameter("sixty", sixty,
	// TemporalType.DATE);
	// lics.addAll(query.getResultList());
	// query = s3.createQuery(nlQ).setParameter("today", today,
	// TemporalType.DATE).setParameter("sixty", sixty,
	// TemporalType.DATE);
	// lics.addAll(query.getResultList());
	// query = s4.createQuery(nlQ).setParameter("today", today,
	// TemporalType.DATE).setParameter("sixty", sixty,
	// TemporalType.DATE);
	// lics.addAll(query.getResultList());
	//
	// }

	// private void fillInvs() {
	// List<Branch> branches = basePersistence.find(Branch.class, new Filter());
	// // new SpectrId()
	// // new Pair<Branch, Invoice>(first, second)
	//
	// String invQ =
	// "select i from Invoice i where i.isPaid = false and i.date > :today";
	// // today.add(Calendar.DAY_OF_MONTH, -30);
	// Query query = s1.createQuery(invQ).setParameter("today", today,
	// TemporalType.DATE);
	// invs = query.getResultList();
	// query = s2.createQuery(invQ).setParameter("today", today,
	// TemporalType.DATE);
	// invs.addAll(query.getResultList());
	// query = s3.createQuery(invQ).setParameter("today", today,
	// TemporalType.DATE);
	// invs.addAll(query.getResultList());
	// query = s4.createQuery(invQ).setParameter("today", today,
	// TemporalType.DATE);
	// invs.addAll(query.getResultList());
	// }

	// private Contragent getContragentByGuid(EntityManager em, String guid) {
	// Query deviceQuery = em.createQuery(
	// "select d from Device d where d.guid = :guid").setParameter(
	// "guid", guid);
	// List<Device> devList = deviceQuery.getResultList();
	// return (devList.size() > 0) ? devList.get(0).getNet().getContragent()
	// : null;
	// }
	//
	// private List<Device> fillCertToAgent() {
	// certToAgent = new HashMap<DeviceCertificate, Contragent>();
	// List<Device> result = new ArrayList<Device>();
	// for (DeviceCertificate dc : certs) {
	// String guid = dc.getDeviceGuid();
	// Contragent agent = getContragentByGuid(s1, guid);
	// if (agent == null)
	// agent = getContragentByGuid(s2, guid);
	// if (agent == null)
	// agent = getContragentByGuid(s3, guid);
	// if (agent == null)
	// agent = getContragentByGuid(s4, guid);
	// if (agent == null)
	// throw new IllegalArgumentException(
	// "Contragent not found with device guid " + guid);
	// certToAgent.put(dc, agent);
	// }
	// return result;
	// }
	//
	// private void fillCerts() {
	// String dcQ = "select dc from DeviceCertificate dc "
	// + "where dc.expireDate BETWEEN :today AND :sixty";
	// // today.add(Calendar.DAY_OF_MONTH, -30); //TODO
	// Calendar sixty = (Calendar) today.clone();
	// sixty.add(Calendar.DAY_OF_MONTH, 60);
	// Query query = eis.createQuery(dcQ).setParameter("today", today,
	// TemporalType.DATE).setParameter("sixty", sixty,
	// TemporalType.DATE);
	// certs = query.getResultList();
	// }

	public void sendEmail(String email, String subj, String text) {
		if (debug) {
			System.out.println("Email to " + email + " " + subj + " " + text);
			return;
		}

		logger.debug("Sending email to " + email + ", " + subj);
		if (!debugEmail)
			sendEmail(session, email, subj, text);
	}

	public static void sendEmail(Session session, String email, String subj,
			String text) {

		Message msg = new MimeMessage(session);
		try {
			msg.setSubject(subj);
			msg.setSentDate(new Date());
			msg.setFrom(); // "portal@urfc.ru");
			msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
					email, // "natali@u-systems.ru", //TODO change to email
					false));
			MimeBodyPart mbp = new MimeBodyPart();
			mbp.setText(text);
			Multipart mp = new MimeMultipart();
			mp.addBodyPart(mbp);
			msg.setContent(mp);
			Transport.send(msg);
		} catch (MessagingException e) {
			e.printStackTrace();
		}
	}

	public EntityManager choseEntityManager(Branch branch) {

		if (branch.codeEquals(Branch.SVERD)) {
			return branch1EntityManager;
		}
		if (branch.codeEquals(Branch.KURGAN)) {
			return branch2EntityManager;
		}
		return null;
	}

	// public class NTDao extends BaseDao {
	public void fillEMs() {
		Query query = sys.createQuery("select fil from Branch fil");
		List<Branch> fils = query.getResultList();
		for (Branch fil : fils) {
			EntityManager em = choseEntityManager(fil); // Contragent.class);
			if (em != null) {
				filCodes.add(fil.getCode());
				ems.add(em);
			}
		}
	}

	// }

	/*
	 * eis.DeviceCertificate (deviceGuid, seria, number, issueDate, expireDate)
	 * spectr1.Device (guid, net) spectr1.Invoice (contragent, isPaid, Name,
	 * number, date) spectr1.NetLicense (state, number, issueDate, expireDate,
	 * net) spectr1.NetWithLicense(contragent) spectr1.Contragent.email
	 * sys.NotificationSettings (client,useGlobal,global
	 * deviceCertificateExpiring, netLicenseExpiring, expirationNotifyInterval
	 * invoiceUnpaidDays, invoiceUnpaidNotifyInterval sys.Client(contragent)
	 */
	@SuppressWarnings("unused")
	@Schedule(second = "0", minute = "0", hour = "5", dayOfWeek = "*", dayOfMonth = "*", month = "*", year = "*", info = "MyTimer")
	// @Schedule(second = "*/15", minute = "*", hour = "8-23", dayOfWeek =
	// "Mon-Fri", dayOfMonth = "*", month = "*", year = "*", info = "MyTimer")
	public void scheduledTimeout(final Timer t) {

		// DmsTest dt = new DmsTest();
		// dt.SendMsg();
		// if (true) return;

		session = null;
		try {
//		    Properties props = new Properties();
//		     props.put("mail.smtp.host", "10.0.1.2");
//
//		    // create some properties and get the default Session
//		    Session session = Session.getDefaultInstance(props, null);
		    
			InitialContext ic = new InitialContext();
			session = (Session) ic.lookup("mail/MyMailSession"); // "java:comp/env/mail/MyMailSession";
			// sendEmail("kopelev-ab@u-systems.ru", "11", "22\n33");

			fillEMs(); // new NTDao().
			logger.info("Start notification");
			go();

			// Properties props = session.getProperties();
			// props.put("mail.from", "user2@mailserver.com");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void testDao() {
		/* new NTDao(). */fillEMs();
		int c = ems.size();
	}

	private Session session;
}
